﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

namespace Interfleet.SE.UICompiler.Core.ClosureCompilerREST
{
    /// <summary>
    /// This class builds up a html post string for the Closure Compiler REST API
    /// </summary>
    public class CCRESTArgumentBuilder : ArgumentBuilder
    {
        #region Constructor
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="arguments"><see cref="Arguments"/> for compilation</param>
        /// <seealso cref="Arguments"/>
        public CCRESTArgumentBuilder(Arguments arguments)
            : this(arguments, new FileProvider(), new CCRESTCompileOptions(), "compiled_code")
        { }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="arguments"><see cref="Arguments"/> for compilation</param>
        /// <param name="outputInfo">output info parameter for Closure Compiler
        /// <list type="bullet">
        /// <item>compiled_code</item>
        /// <item>statistics</item>
        /// <item>warnings</item>
        /// <item>errors</item>
        /// </list></param>
        /// <seealso cref="Arguments"/>
        public CCRESTArgumentBuilder(Arguments arguments, string outputInfo)
            : this(arguments, new FileProvider(), new CCRESTCompileOptions(), outputInfo)
        { }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="arguments"><see cref="Arguments"/> for compilation</param>
        /// <param name="fileProvider">An instance of <see cref="IFileProvider"></see></param>
        /// <param name="compileOptions"><see cref="CompileOptions"/></param>
        /// <seealso cref="Arguments"/>
        /// <seealso cref="IFileProvider"/>
        /// <see cref="CompileOptions"/>
        public CCRESTArgumentBuilder(Arguments arguments, IFileProvider fileProvider, CompileOptions compileOptions)
            : this(arguments, fileProvider, compileOptions, "compiled_code")
        { }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="arguments"><see cref="Arguments"/> for compilation</param>
        /// <param name="fileProvider">An instance of <see cref="IFileProvider"></see></param>
        /// <param name="compileOptions"><see cref="CompileOptions"/></param>
        /// <param name="outputInfo">output info parameter for Closure Compiler
        /// <list type="bullet">
        /// <item>compiled_code</item>
        /// <item>statistics</item>
        /// <item>warnings</item>
        /// <item>errors</item>
        /// </list></param>
        public CCRESTArgumentBuilder(Arguments arguments, IFileProvider fileProvider, CompileOptions compileOptions, string outputInfo)
            : base(arguments, fileProvider, compileOptions) 
        {
            OutputInfo = outputInfo;
        }
        #endregion

        private string OutputInfo
        {
            get;
            set;
        }

        private void SetJSCode(StringBuilder sb)
        {
            sb.Append("js_code=");
            foreach (var file in Arguments.Files)
            {
                var fileContent = FileProvider.ReadFileToEnd(file);
                fileContent = HttpEncode(fileContent);
                sb.Append(fileContent);
            }
        }

        private string HttpEncode(string str)
        {
            return System.Uri.EscapeDataString(str);
        }

        /// <summary>
        /// Builds up a html post string
        /// </summary>
        /// <returns>A valid post string for the Closure Compiler</returns>
        public override string Build()
        {
            var sb = new StringBuilder();
            SetJSCode(sb);
            sb.AppendFormat("&compilation_level={0}", Arguments.CompileOption);
            sb.Append("&output_format=xml");
            sb.AppendFormat("&output_info={0}", OutputInfo);
            return sb.ToString();
        }
    }
}
